package com.lightsaber.trade.core.common.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.xwork.StringUtils;

/**
 * Calculator
 * 
 * @author LiuJian
 * 
 */
public final class Calc {

    private Calc() {
    }

    /**
     * Rounding decimals to retain two significant decimal, comma as the
     * thousands separator
     * 
     * @author jianliu
     * 
     * @param null, or "1111.115", or "1,111.115", or a number
     * @return "1,111.12"
     */
    public static String formatCommaAnd2Point(final Object obj) {
        String val = String.valueOf(obj);
        if (val == null) {
            return "0.00";
        }

        val = val.replaceAll(",", "");
        if (!NumberUtils.isNumber(val)) {
            return "0.00";
        }

        BigDecimal decimal = new BigDecimal(val);
        decimal = decimal.setScale(2, RoundingMode.HALF_UP);

        DecimalFormat df = new DecimalFormat("#,##0.00");
        return df.format(decimal);

    }

    /**
     * Rounding decimals to retain effective 0, comma as the thousands separator
     * 
     * @author jianliu
     * 
     * @param null, or "1111.5", or "1,111.5", or a number
     * @return "1,112"
     */
    public static String formatCommaAndNoPoint(final Object obj) {
        String val = String.valueOf(obj);
        if (val == null) {
            return "0";
        }

        val = val.replaceAll(",", "");
        if (!NumberUtils.isNumber(val)) {
            return "0";
        }

        BigDecimal decimal = new BigDecimal(val);
        decimal = decimal.setScale(0, RoundingMode.UP);

        DecimalFormat df = new DecimalFormat("#,###");
        return df.format(decimal);
    }

    /**
     * Divides two numbers, return percentage and retain two significant decimal
     * places<br>
     * 
     * Example: 1/3 = 33.33%
     * 
     * @param v1
     * @param v2
     * @return (v1/v2)*100%
     */
    public static String div2Percentage(final BigDecimal b1, final BigDecimal b2) {
        if (b2.equals(BigDecimal.ZERO)) {
            return "0";
        }

        BigDecimal db = b1.divide(b2, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))
                .setScale(2);

        return db.toString() + "%";

    }

    /**
     * Divides two numbers, retain two significant decimal places<br>
     * Example: 1/3 = 0.33
     * 
     * @param v1
     * @param v2
     * @return v1/v2
     */
    public static String div(final Object obj1, final Object obj2) {

        String v1 = obj1.toString();
        String v2 = obj2.toString();

        if (v2.equals("0")) {
            return "0";
        }

        BigDecimal db = new BigDecimal(v1).divide(new BigDecimal(v2), 2, RoundingMode.UP);

        return db.toString();

    }

    /**
     * Divides two numbers, retain two significant decimal places<br>
     * Example: 7/3 = 2
     * 
     * @param v1
     * @param v2
     * @return v1/v2
     */
    public static String div2Integer(final Object obj1, final Object obj2) {
        String v1 = obj1.toString();
        String v2 = obj2.toString();

        if (v2.equals("0")) {
            return "0";
        }

        BigDecimal db = new BigDecimal(v1).divideToIntegralValue(new BigDecimal(v2));

        return db.toString();

    }

    /**
     * @param obj1
     * @param obj2
     * @param obj3
     * @return (obj1/obj2)*obj3
     */
    public static Integer divMul2Integer(final Object obj1, final Object obj2, final Object obj3) {
        String v1 = obj1.toString();
        String v2 = obj2.toString();
        String v3 = obj3.toString();

        if (StringUtils.isBlank(v1)) {
            return 0;
        }

        if (v2.equals("0")) {
            return 0;
        }

        BigDecimal db = (new BigDecimal(v1).divide(new BigDecimal(v2), 2, RoundingMode.UP))
                .multiply(new BigDecimal(v3));

        return Integer.valueOf(db.setScale(0, RoundingMode.UP).toString());

    }

    /**
     * Convert digit sequence to character string, <br>
     * Example: "0123456" -> "ABCDEFG"
     * 
     * @param digit
     * @return
     */
    public static String digit2Str(final Object obj) {
        String digit = String.valueOf(obj);

        StringBuilder letterSB = new StringBuilder();
        char[] digits = digit.toCharArray();

        for (char c : digits) {
            int i = Integer.valueOf(String.valueOf(c));
            i = i + 65;// From the letter "A"
            letterSB.append((char) i);
        }

        return letterSB.toString();
    }

    public static String leaveTwoDigital(Double d) {
        DecimalFormat df = new DecimalFormat(".##");

        return df.format(d);
    }

}
